#include "Bat.h"

CBat::CBat(CPhysics* pPhysics, float3 f3Position, GLfloat fSurface[4])
{
	//non-ODE init routines:
	m_bMarked = false;	//not marked to delete
	m_fLength = 3.0f;	//length of an Bat

	m_fSpeed = 5.0f;	//speed = 5units/sec.

	for(int i=0; i < 4; i++)	//set bat surface
	{
		m_fBatSurface[i] = fSurface[i];
	}

	m_bOver = false;

	m_pCamera = new CCamera();

	//position of camera - behind the player
	float3 f3CamPosition = f3Position*1.5f;
	f3CamPosition.y += 13.0f;

	float3 f3CamTarget = f3Position*0.5f;

	m_pCamera->SetPosition(f3CamPosition);
	m_pCamera->SetTarget(f3CamTarget);	//look on the board-center

	//player specific routines:
	m_iLives = 3;
	m_liScore = 0;
	m_bRelease = false;

	//ODE init routines:
	m_body = dBodyCreate( pPhysics->GetWorld() );
		
	m_geom = dCreateBox(pPhysics->GetSpace(), m_fLength, 1.0, 1.0);
		
	dGeomSetBody(m_geom, m_body);

	dMassSetBox(&m_mass, 10, m_fLength, 1.0f, 1.0f);
	dBodySetMass(m_body, &m_mass);

	dBodySetPosition(m_body, f3Position.x, f3Position.y, f3Position.z);


	//create track joint
	dJointID jointTrack = dJointCreateSlider(pPhysics->GetWorld(), 0);
	dJointAttach(jointTrack, m_body, 0);
	dJointSetSliderAxis(jointTrack, 1.0f, 0.0f, 0.0f);

	dBodySetData(m_body, this);

	
}

CBat::~CBat(void)
{
	dBodyDestroy(m_body);
	dGeomDestroy(m_geom);
	delete m_pCamera;
}

int CBat::Draw()
{
	glPushMatrix();

	SetupMatrices();

	glEnable(GL_TEXTURE_2D);
	glBindTexture( GL_TEXTURE_2D, m_uiTexture );

	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, m_fBatSurface);
	glBegin(GL_QUADS);
	/* przednia sciana */
	glNormal3d( 0.0, 0.0, -1.0);
	glTexCoord2d(0.0f, 0.0f); glVertex3d( -(m_fLength/2), -0.5, -0.5);
	glTexCoord2d(0.0f, 1.0f); glVertex3d( -(m_fLength/2), 0.5, -0.5);
	glTexCoord2d(2.0f, 1.0f); glVertex3d( (m_fLength/2), 0.5, -0.5);
	glTexCoord2d(2.0f, 0.0f); glVertex3d( (m_fLength/2), -0.5, -0.5);

	/* tylna sciana */
	glNormal3d( 0.0, 0.0, 1.0);
	glTexCoord2d(0.0f, 0.0f); glVertex3d( -(m_fLength/2), -0.5, 0.5);
	glTexCoord2d(0.0f, 1.0f); glVertex3d( -(m_fLength/2), 0.5, 0.5);
	glTexCoord2d(2.0f, 1.0f); glVertex3d( (m_fLength/2), 0.5, 0.5);
	glTexCoord2d(2.0f, 0.0f); glVertex3d( (m_fLength/2), -0.5, 0.5);

	/* gorna sciana */
	glNormal3d( 0.0, 1.0, 0.0);
	glTexCoord2d(0.0f, 0.0f); glVertex3d( -(m_fLength/2), 0.5, -0.5);
	glTexCoord2d(0.0f, 1.0f); glVertex3d( -(m_fLength/2), 0.5, 0.5);
	glTexCoord2d(2.0f, 1.0f); glVertex3d( (m_fLength/2), 0.5, 0.5);
	glTexCoord2d(2.0f, 0.0f); glVertex3d( (m_fLength/2), 0.5, -0.5);

	/* dolna sciana */
	glNormal3d( 0.0, -1.0, 0.0);
	glTexCoord2d(0.0f, 0.0f); glVertex3d( -(m_fLength/2), -0.5, -0.5);
	glTexCoord2d(0.0f, 1.0f); glVertex3d( -(m_fLength/2), -0.5, 0.5);
	glTexCoord2d(2.0f, 1.0f); glVertex3d( (m_fLength/2), -0.5, 0.5);
	glTexCoord2d(2.0f, 0.0f); glVertex3d( (m_fLength/2), -0.5, -0.5);
	
	/* lewa boczna sciana */
	glNormal3d( -1.0, 0.0, 0.0);
	glTexCoord2d(0.0f, 0.0f); glVertex3d( -(m_fLength/2), -0.5, -0.5);
	glTexCoord2d(0.0f, 1.0f); glVertex3d( -(m_fLength/2), 0.5, -0.5);
	glTexCoord2d(1.0f, 1.0f); glVertex3d( -(m_fLength/2), 0.5, 0.5);
	glTexCoord2d(1.0f, 0.0f); glVertex3d( -(m_fLength/2), -0.5, 0.5);

	/* prawa boczna sciana */
	glNormal3d( 1.0, 0.0, 0.0);
	glTexCoord2d(0.0f, 0.0f); glVertex3d( (m_fLength/2), -0.5, -0.5);
	glTexCoord2d(0.0f, 1.0f); glVertex3d( (m_fLength/2), -0.5, 0.5);
	glTexCoord2d(1.0f, 1.0f); glVertex3d( (m_fLength/2), 0.5, 0.5);
	glTexCoord2d(1.0f, 0.0f); glVertex3d( (m_fLength/2), 0.5, -0.5);

	glEnd();

	glDisable(GL_TEXTURE_2D);

	glPopMatrix();
	return 0;
}

int CBat::MoveLeft()
{
	const double* dCurrPos = dBodyGetPosition(m_body);
	double dNewX = dCurrPos[0] - (m_fSpeed * g_fTime);
	//keep the bat inside board
	if(dNewX < (-10.0 + m_fLength/2))
	{
		dNewX = (-10.0 + m_fLength/2);
	}
	dBodySetPosition(m_body, dNewX, dCurrPos[1], dCurrPos[2]);

	return 0;
}

int CBat::MoveRight()
{
	const double* dCurrPos = dBodyGetPosition(m_body);
	double dNewX = dCurrPos[0] + (m_fSpeed * g_fTime);
	//keep the bat inside board
	if(dNewX > (10.0 - m_fLength/2))
	{
		dNewX = (10.0 - m_fLength/2);
	}
	dBodySetPosition(m_body, dNewX, dCurrPos[1], dCurrPos[2]);

	return 0;
}

int CBat::Fail()
{
	if(m_iLives > 0)
	{
		m_iLives --;
	}
	else
	{
		m_bOver = true;
	}
	return 0;
}

int CBat::Update()
{
	//update camera (if dynamic):
	if(m_pCamera->IsDynamic()){
		const double* dPos = dBodyGetPosition(m_body);

		float3 f3CamPos = m_pCamera->GetPosition();
		f3CamPos.x = (float)dPos[0];
		m_pCamera->SetPosition(f3CamPos);

		float3 f3CamTarget = m_pCamera->GetTarget();
		f3CamTarget.x = (float)dPos[0] * 0.5f;
		m_pCamera->SetTarget(f3CamTarget);
	}

	if(m_bOver)
	{
		return -1;	//if player has no more lives, return -1 to tell, that game is over
	}
	return 0;
}

int CBat::Score(int iValue)
{
	m_liScore += iValue;
	return 0;
}

/****************************************************************************/
/* Enable/disable dynamic camera                                            */
/****************************************************************************/
void CBat::SwitchDynamicCamera(bool bEnabled)
{
	m_pCamera->SetDynamic(bEnabled);

	//if dynamic is disabled - reset camera position to default - centered, behind the player 
	if(!bEnabled)
	{
		float3 f3CamPos = m_pCamera->GetPosition();
		f3CamPos.x = 0.0f;
		m_pCamera->SetPosition(f3CamPos);

		float3 f3CamTarget = m_pCamera->GetTarget();
		f3CamTarget.x = 0.0f;
		m_pCamera->SetTarget(f3CamTarget);
	}
}

void CBat::LoadTexture()
{
	m_uiTexture = CUtils::LoadRAW("boat.raw", 256, 256);
}